﻿// Most of the code here is taken from the sample code from the following thread
// http://forums.netduino.com/index.php?/topic/831-music-with-a-piezo-speaker/
// the code I've put together is released under the Ms-PL license (http://christocnetduino.codeplex.com/license), code from other authors was found in the public domain

// requires the NetduinoGo.PeizoBuzzer DLL www.netduino.com

using System.Threading;
using NetduinoGo;
using SecretLabs.NETMF.Hardware.NetduinoGo;

namespace NetduinoGoPiezoTest
{
    public class Program
    {
        //get the PiezoBuzzer module, plugged in to Socket 1
        static readonly PiezoBuzzer Pb1 = new PiezoBuzzer(GoSockets.Socket1);

        //three "songs" that are in the thread
        static readonly string[] Tunes = new[] 
            {
                "C * F / F * F A G / F * G A F / F A + C D" , // Auld Lang Syne
                "D / D * * E D G * F# / / D / D * * E D A * G / / D / D * * + D - B G F# * E / / + C / C * * - B G A * G", // Happy birthday
                "C C G G A A * G / F F E E D D * C / G G F F E E * D / G G F F E E * D / C C G G A A * G / F F E E D D * C" , // twinkle, twinkle
                "A B + C D E F# G# A G F E D C - B A" // melodic minor scale
            };

        public static void Main()
        {
            // this program is pretty simple, rinse and repeat

            while(true)
            {
                for (int i = 0; i <= 3;i++ )
                {
                    Play(Tunes[i], 4, 333);

                    //play 1 second of nothing
                    Play(0,1000);
                }
            }
        }


        static private bool _busy;
        static public void Play(float frequency, int duration)
        {
            if (!_busy)
            {
                _busy = true;

                Pb1.SetFrequency(frequency);
                
                Thread.Sleep(duration);

                // turn the speaker off
                Pb1.SetFrequency(0);
                _busy = false;
            }
        }

        static public void Play(Note[] notes)
        {
            foreach (Note note in notes)
            {
                Play(note.Frequency, note.Duration);
            }
        }

        static public void Play(string sequence, int initialOctave, int initialTempo)
        {
            string[] notes = sequence.Split(' ');

            // initialise the Note object we'll reuse for playing each note
            var note = new Note(initialOctave, "c", initialTempo);

            foreach (string item in notes)
            {
                if (item != "")
                {
                    if (item == "*") // double the current tempo
                    {
                        note.Duration *= 2;
                    }
                    else if (item == "/") // halve the current tempo
                    {
                        note.Duration /= 2;
                    }
                    else if (item == "-") // move to the octave below
                    {
                        if (note.Octave > 0)
                            note.Octave--;
                    }
                    else if (item == "+") // move to the octave above
                    {
                        if (note.Octave < 8)
                            note.Octave++;
                    }
                    else
                    {
                        note.NoteLetter = item;
                        Play(note.Frequency, note.Duration);

                        // small gap between notes
                        Thread.Sleep(10);
                    }
                }
            }
        }
    }
}
